package ro.qi.framework.sys.i18n.currencies;

import java.util.Calendar;
import java.util.Enumeration;
import java.util.Hashtable;

import ro.qi.framework.sys.debug.Logger;
import ro.qi.framework.sys.i18n.currencies.entities.Currency;
import ro.qi.framework.sys.i18n.currencies.entities.CurrencyCollection;

/**
 * @author George Pogorelschi
 *
 * To change the template for this generated type comment go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */
public class CurrenciesManager {


	private static Hashtable<Integer, Currency> cachedCurrenciesById = new Hashtable<Integer, Currency>();
	private static Hashtable<String, Currency> cachedCurrenciesByAlphanumericCode = new Hashtable<String, Currency>();
	private static Hashtable<String, Currency> cachedCurrenciesByNumericCode = new Hashtable<String, Currency>();

	private static CurrencyCollection currencies = null;

	private static CurrenciesManager instance = null;

	private CurrenciesManager() {
	}

	public void init() {
		cachedCurrenciesById = new Hashtable<Integer, Currency>();
		cachedCurrenciesByAlphanumericCode = new Hashtable<String, Currency>();
		cachedCurrenciesByNumericCode = new Hashtable<String, Currency>();
		cacheCurrencies();
	}

	public static synchronized CurrenciesManager getInstance() {
		if (instance == null) {
			instance = new CurrenciesManager();
			instance.init();
		}
		return instance;
	}

	public void stop() {
		cachedCurrenciesById = new Hashtable<Integer, Currency>();
		cachedCurrenciesByAlphanumericCode = new Hashtable<String, Currency>();
		cachedCurrenciesByNumericCode = new Hashtable<String, Currency>();
		instance = null;
	}

	public static boolean isStarted() {
		return instance != null;
	}

	public void refreshCache() {
		cacheCurrencies();
	}

	public String getCache() {
		StringBuffer stringBuffer = new StringBuffer();
		
		stringBuffer.append("<p>cachedCurrenciesById:</p>");
		Enumeration enum1 = cachedCurrenciesById.keys ();
		while (enum1.hasMoreElements ()) {
			Integer key = (Integer) enum1.nextElement ();
			Currency value = (Currency) cachedCurrenciesById.get(key);
			stringBuffer.append(key + ": " + value.getId() + "<br>");
		}

		stringBuffer.append("<p>cachedCurrenciesByAlphanumericCode:</p>");
		Enumeration enum2 = cachedCurrenciesByAlphanumericCode.keys ();
		while (enum2.hasMoreElements ()) {
			String key = (String) enum2.nextElement ();
			Currency value = (Currency) cachedCurrenciesByAlphanumericCode.get(key);
			stringBuffer.append(key + ": " + value.getId() + "<br>");
		}
		
		stringBuffer.append("<p>cachedCurrenciesByNumericCode:</p>");
		Enumeration enum3 = cachedCurrenciesByNumericCode.keys ();
		while (enum3.hasMoreElements ()) {
			String key = (String) enum3.nextElement ();
			Currency value = (Currency) cachedCurrenciesByNumericCode.get(key);
			stringBuffer.append(key + ": " + value.getId() + "<br>");
		}
		
		return stringBuffer.toString();
	}

	/*
	 * 
	 */
	public void cacheCurrencies() {

		Logger.info(this, "Start caching currencies");

		Calendar startTime = Calendar.getInstance();

		// retrieve locales
		currencies = new CurrencyCollection();

		for (int idx = 0; idx < currencies.getCollectionSize(); idx++) {
			Currency currency = currencies.getCurrency(idx);

			Logger.info(this, "Currency: " + currency.getName() + " (" + currency.getIsoAlphanumericCode() + " - " + currency.getId() + ") cached.");

			cachedCurrenciesById.put(new Integer(currency.getId()), currency);
			cachedCurrenciesByAlphanumericCode.put(currency.getIsoAlphanumericCode(), currency);
			cachedCurrenciesByNumericCode.put(currency.getIsoNumericCode(), currency);
			
		}

		Calendar endTime = Calendar.getInstance();
		double diff = endTime.getTime().getTime() - startTime.getTime().getTime();

		Logger.info(this, "End caching currencies (" + diff + " ms)");
		Logger.info(this, "Readed:\t" + currencies.getCollectionSize() + " currencies");
	}

	/**
	 *	getLocale by id
	 * 
	 */
	public Currency getCurrency(int currencyId) { // throws LocalesException {
		if (cachedCurrenciesById.containsKey(new Integer(currencyId)) ) {
			return (Currency)cachedCurrenciesById.get(new Integer(currencyId));
		} else {
			Logger.warning(this, "Currency id \"" + currencyId + "\" not found in cache.");
			// TODO: throw currency exception
//			throw new LocalesExceptionLocaleNotFound();
			return new Currency();
		}
	}

	/**
	 *	getLocale by code 
	 * 
	 */
	public Currency getCurrency(String currencyAlphanumericCode) { // throws LocalesException {
		if (cachedCurrenciesByAlphanumericCode.containsKey(currencyAlphanumericCode)) {
			return (Currency)cachedCurrenciesByAlphanumericCode.get(currencyAlphanumericCode);
		} else {
			Logger.warning(this, "Currency code \"" + currencyAlphanumericCode + "\" not found in cache.");
			// TODO: throw currency exception
//			throw new LocalesExceptionLocaleNotFound();
			return new Currency();
		}

	}

	public CurrencyCollection getCollection() {
		return currencies;
	}

	public int getCollectionSize() {
		return cachedCurrenciesById.size();
	}

	public int getId(int index) {
		return getCurrency(currencies.getId(index)).getId();
	}

}
